package com.sunlands.deskmate.message.handler.storager.unsync;

import com.sunlands.deskmate.message.entity.Messages;
import com.sunlands.deskmate.message.handler.storager.MultipleSortedStorager;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundZSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author anjunling@sunlands.com
 * 使用redis的factor特性, 按照sessionId: messages : factor(score)  的格式记录当前连接一条messageId. 用来确保信息发送顺序
 */
@Component("redisZSetStorager")
@Slf4j
public class RedisZSetStorager implements MultipleSortedStorager<Messages> {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public boolean add(String key, Messages message, long factor) {
        RScoredSortedSet<Messages> messageStore = redissonClient.getScoredSortedSet(key);
        messageStore.expire(24, TimeUnit.HOURS);
        log.info("factor = {}, message = {}",factor, message);
        Boolean result = messageStore.add(((Long) factor).doubleValue(), message);
        log.debug("storage: key={}, messages={}, factor={}, result={}", key, message, factor, result);
        return result;
    }

    public List<Messages> rangeByFactor(String key, Long min, Long max){
        RScoredSortedSet<Messages> messageStore = redissonClient.getScoredSortedSet(key);
        messageStore.expire(24, TimeUnit.HOURS);
        Collection<Messages> messageString = messageStore.valueRange(min.doubleValue(), true, max.doubleValue(), true);
        if(Objects.isNull(messageString) || messageString.isEmpty()){
            return Collections.emptyList();
        }
        log.info("获取未读消息 message = {}", messageString);
        return new ArrayList<>(messageString);
    }

    /**
     * 获取从score=scoreMin开始的count个数的value值, score=scoreMin的项必须存在,
     * 如果没有scoreMin, 则从队列的首条开始计算
     *
     * @param key
     * @param count
     * @return
     */
    @Override
    public List<Messages> rangeByFactorByCount(String key, int count) {

        RScoredSortedSet<Messages> messageStore = redissonClient.getScoredSortedSet(key);
        Collection<Messages> messageString = messageStore.valueRange(0, count);
        if(Objects.isNull(messageString) || messageString.isEmpty()){
            return Collections.emptyList();
        }
        log.info("获取未读消息 message = {}", messageString);
        return new ArrayList<>(messageString);
    }

    @Override
    public long count(String id) {
        BoundZSetOperations boundZSetOperations = redisTemplate.boundZSetOps(id);
        Long size = boundZSetOperations.size();
        return size == null ? 0 : size;
    }

    @Override
    public List<Messages> rangeByIndex(String id, long min, long max) {
        return Collections.emptyList();
    }

    @Override
    public void removeByFactor(String key, long min, long max) {
        BoundZSetOperations<String, String> boundZSetOperations = redisTemplate.boundZSetOps(key);
        boundZSetOperations.expire(24, TimeUnit.HOURS);
        double minScore = ((Long) min).doubleValue();
        double maxScore = ((Long) max).doubleValue();
        boundZSetOperations.removeRangeByScore(minScore, maxScore);
    }

    @Override
    public void removeByIndex(String id, long min, long max) {
        // Do nothing because unused
    }

    @Override
    public void del(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public boolean add(String id, Messages message) {
        return false;
    }

    @Override
    public Messages poll() {
        return null;
    }

    @Override
    public Messages peek() {
        return null;
    }

    @Override
    public boolean remove() {
        return false;
    }
}
